package com.hu.bgp.framework.clientapi;


import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.client.rpc.SerializationStreamFactory;
import com.google.gwt.user.client.rpc.SerializationStreamReader;
import com.google.gwt.user.client.rpc.ServiceDefTarget;

import com.google.gwt.user.client.ui.Widget;



/**
 * Schrijf een subklasse van deze klasse om een client (game UI) te
 * implementeren.
 * 
 * @author ejvos
 */
public abstract class Client implements FailureHandler, EntryPoint
{
	private BoardGameServiceAsync bgpService;
//	private ClientGameContext clientGameContext;
	boolean isLoaded = false;
	public final void onModuleLoad()
	{
		initJsNativeInterface();
		// get a binding to the servlet
		bgpService = GWT.create(BoardGameService.class);
		ServiceDefTarget target = (ServiceDefTarget) bgpService;
		target.setServiceEntryPoint("/bgp/games");
	
		//add some defautl connectin screen?...
		//final module load done by native call from the bgp container
	}
	public void isConnected(boolean value)
	{
		//TODO other stuff ?...
		onModuleLoad();
	}
	protected abstract void onModuleLoad2();

	protected abstract void handleMessage(ServerToClientMessage message);

	protected abstract Widget getPlayArea();

	protected void sendMessageAndIgnoreOutcome(ClientToServerMessage message)
	{
		bgpService.handleMessage(message, new FailureHandlingCallback<Void>(this)
		{
			public void onSuccess(Void result)
			{
			}
		});
	}
	
	
	public Object clientDeserializer(String encodedPayload)
		throws SerializationException {
		// Create the serialization stream factory
		SerializationStreamFactory serializationFactory = GWT.create(BoardGameService.class);
		
		// Create a stream reader
		SerializationStreamReader streamReader = serializationFactory.createStreamReader(encodedPayload);
		// Deserialize the instance
	return streamReader.readObject();
	}
	
	public void sendRawGWTObject(String payload)
	{
		Window.alert(payload);
		try {
			ServerToClientMessage x =(ServerToClientMessage) clientDeserializer(payload);
			handleMessage(x);
		} catch (SerializationException e) {
			// TODO Auto-generated catch block
			Window.alert("[ERROR]" + e.getMessage() + "\n" +e.toString());
			e.printStackTrace();
		}
	}
	public boolean getIsloaded()
	{
		return isLoaded;
	}
	//TODO put native methods in bgp js namespace...
	public void initJsNativeInterface()
	{
		exportSendRawGWTObject();
		exportIsConnected();
		exportIsloaded();
	}
	public native void exportInitNameSpace() /*-{
		if(!$wnd[@com.hu.bgp.framework.clientapi.BgpClientEnvironment::BGP_NATIVE_NS]){
			$wnd[@com.hu.bgp.framework.clientapi.BgpClientEnvironment::BGP_NATIVE_NS] = []};
			 
		
   
 }-*/;
	
	public native void exportSendRawGWTObject() /*-{
     $wnd[@com.hu.bgp.framework.clientapi.BgpClientEnvironment::BGP_NATIVE_NS].sendRawGWTObject =
        $entry(this.@com.hu.bgp.framework.clientapi.Client::sendRawGWTObject(Ljava/lang/String;));
  }-*/;
	public native void exportIsConnected() /*-{
     $wnd[@com.hu.bgp.framework.clientapi.BgpClientEnvironment::BGP_NATIVE_NS].isConnected =
       $entry(this.@com.hu.bgp.framework.clientapi.Client::isConnected(Z));
 }-*/;
	public native void exportIsloaded() /*-{
    $wnd[@com.hu.bgp.framework.clientapi.BgpClientEnvironment::BGP_NATIVE_NS].isLoaded =
      $entry(this.@com.hu.bgp.framework.clientapi.Client::getIsloaded());
}-*/;
	

}
